﻿using Furion;
using Furion.DependencyInjection;
using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.DependencyInjection;
using MultiTenant.Core;
using MultiTenant.Core.Locators;
using System;
using System.Linq;
using YFurion.Extensions;
using YFurion.Session;

namespace MultiTenant.EntityFramework.Core
{
    public static class MultiTenantExtensions
    {
        public static string GetConnectionString(this IYSession ySession, string defaultConnectionString)
        {
            MyTenant tenant = ySession.GetTenant();
            if (tenant == null)
            {
                return defaultConnectionString;
            }

            switch (tenant.Type)
            {
                case 0:
                default:
                    return defaultConnectionString;
                case 1:
                    return tenant.ConnectionString;
            }
        }

        public static MyTenant GetTenant(this IYSession ySession)
        {
            // 判断 HttpContext 是否存在
            HttpContext httpContext = App.HttpContext;
            if (httpContext == null)
            {
                return default;
            }

            string host = httpContext.Request.Headers["MultiTenantHost"];
            if (host.IsNullOrWhiteSpace())
            {
                return default;
            }

            // 获取服务提供器
            IServiceProvider serviceProvider = httpContext.RequestServices;
            IDistributedCache distributedCache = serviceProvider.GetService<IDistributedCache>();
            MyTenant tenant = distributedCache.GetOrCreate($"MultiTenant#{host}", () =>
            {
                // 获取新的租户数据库上下文
                Func<Type, IScoped, DbContext> dbContextResolve = serviceProvider.GetService<Func<Type, IScoped, DbContext>>();
                if (dbContextResolve == null)
                {
                    return default;
                }

                DbContext tenantDbContext = dbContextResolve(typeof(MultiTenantSlaveDbContextLocator), default);
                MyTenant entity = tenantDbContext.Set<MyTenant>().AsNoTracking().FirstOrDefault(e => e.Host.Equals(host));
                return entity;
            }, distributedCache.GetDefaultDistributedCacheEntryOptions());
            return tenant;
        }
    }
}
